#include "UIEdit.h"
#include "comm.h"
#include "defines.h"
#include "win_gdi.h"
#include <Windows.h>

UIEdit::UIEdit(UIContainer *parent) : UILabel(parent)
{
    this->setName("UIEdit");
    this->setEditable(true);
    this->m_Text.reserve(1024 * 10);         // 预留10KB的空间
    this->m_TextW.reserve(1024 * 10);        // 预留10KB的空间
    this->setPadding(DuiCorner{2, 2, 2, 2}); // 内边距
    // 左上角对齐
    this->setTextAlignX(DUI_TEXT_ALIGN_LEFT);
    this->setTextAlignY(DUI_TEXT_ALIGN_LEFT);
}

UIEdit::~UIEdit()
{
}

std::string UIEdit::getUIType()
{
    return "UIEdit";
}

void UIEdit::onMouseDown(int x, int y)
{
}

void UIEdit::onMouseUp(int x, int y)
{
}

void UIEdit::onMouseMove(int x, int y)
{
}

void UIEdit::onMouseEnter()
{
    UILabel::onMouseEnter();
    printf("UIEdit::onMouseEnter, {%d, %d, %d, %d}\r\n", this->m_Rect.x, this->m_Rect.y, this->m_Rect.w,
           this->m_Rect.h);
    auto mgr = this->getWinManager();
    auto hwnd = (HWND)mgr->hWin;
    if (this->getEditable())
    {
        std::wstring test = L"ABC中";
        auto text_rect = render_measure_text(mgr, test, this->m_FontFamily, this->m_FontSize, this->m_FontWeight);
        CreateCaret(hwnd, 0, 2, text_rect.h);
        ShowCaret(hwnd);
    }
}

void UIEdit::onMouseLeave()
{
    UILabel::onMouseLeave();
    printf("UIEdit::onMouseLeave\r\n");
    auto mgr = this->getWinManager();
    if (this->getEditable())
    {
        HideCaret((HWND)mgr->hWin);
        DestroyCaret();
    }
}

void UIEdit::onMouseWheel(int delta, int x, int y)
{
}

void UIEdit::onKeyDown(int key)
{
}

void UIEdit::onKeyUp(int key)
{
}

void UIEdit::onKeyChar(int key)
{
    printf("UIEdit::onKeyChar, 0x%04X, %C\r\n", key, key);
    if (key > 31 && key < 127)
    {
        this->m_TextW.append(1, (wchar_t)key);
    }
    else
    {
        // https://blog.csdn.net/TLDX_XIONG/article/details/106888906
        switch (key)
        {
        case DUI_KBD_VK_BACK:
            // 退格
            if (this->m_TextW.length() > 0)
            {
                this->m_TextW.pop_back();
            }
            break;
        case DUI_KBD_VK_TAB:
            this->m_TextW.append(1, (wchar_t)'\t');
        break;
        case DUI_KBD_VK_CLEAR:
            this->m_TextW.append(1, (wchar_t)'\r');
        break;
        case DUI_KBD_VK_RETURN:
            this->m_TextW.append(1, (wchar_t)'\n');
        break;
        default:
            break;
        }
    }
}

void UIEdit::onImeChar(int key)
{
    printf("UIEdit::onImeChar, 0x%04X, %C\r\n", key, key);
    // https://www.cnblogs.com/linuxheik/articles/11411124.html
    int cn = 0;
    if (!this->m_bWCharDone)
    {
        // 已经有1个字符了
        this->m_WCharBuff[1] = key;
        this->m_bWCharDone = true;
        cn = 2;
    }
    else
    {
        wchar_t c = key & 0xFFFF;
        if (c >= 0xD800)
        {
            // 生僻字，4个字节，需要等待下一个字符
            this->m_bWCharDone = false;
            this->m_WCharBuff[0] = key;
        }
        else
        {
            this->m_WCharBuff[0] = key;
            this->m_bWCharDone = true;
            cn = 1;
        }
    }

    // 保证一个编码的完整性
    if (cn > 0 && this->m_bWCharDone)
    {
        this->m_TextW.append(this->m_WCharBuff, cn);
    }
}

void UIEdit::onCommand(int command, void *param)
{
}

void UIEdit::onDrawContent(DuiWinManager *mgr, DuiRect &rect_in, DuiRect &rect_out)
{
    // UILabel::onDraw(mgr);
    auto fontFm = (FontFamily *)dui_comm_font_get(this->m_FontFamily);
    auto fontFmCb = (FontFamily *)dui_comm_font_get(this->m_FontFamilyCb);
    auto fontStyle = FontStyleRegular;
    if (this->m_FontWeight > 400)
    {
        fontStyle = FontStyleBold;
    }
    Gdiplus::Font font(fontFm, this->m_FontSize, fontStyle, UnitPixel);
    Gdiplus::Font fontCb(fontFmCb, this->m_FontSize, fontStyle, UnitPixel);

    StringFormat sfmt;
    sfmt.SetAlignment(StringAlignmentNear);
    sfmt.SetLineAlignment(StringAlignmentNear);

    SolidBrush brush(Color(this->m_Color.a, this->m_Color.r, this->m_Color.g, this->m_Color.b));

    auto lines = render_measure_parse_text(mgr, this->m_TextW, font, fontCb, sfmt, this->m_Rect);
    // 更好看的渲染
    mgr->graph->SetTextRenderingHint(TextRenderingHintSystemDefault);
    int xh = 0;
    int xpos = this->m_Rect.x;
    int ypos = this->m_Rect.y;
    int xcur = 0;
    int ycur = 0;
    for (auto it = lines.begin(); it != lines.end(); ++it)
    {
        // 超出范围判定
        if ((ypos + xh) > this->m_Rect.y + this->m_Rect.h)
        {
            break;
        }
        for (auto it2 = it->ichars.begin(); it2 != it->ichars.end(); ++it2)
        {
            if (xh == 0)
            {
                xh = it2->h + it2->y*2;
            }
            if (it2->len > 1)
            {
                mgr->graph->DrawString(it2->c, it2->len, &fontCb, PointF(xpos, ypos), &brush);
            }
            else
            {
                mgr->graph->DrawString(it2->c, it2->len, &font, PointF(xpos, ypos), &brush);
            }
            xpos += it2->w;
            xcur = xpos + 1;
            ycur = ypos + 2;
        }
        xpos = this->m_Rect.x + it->marggin;
        ypos += xh;
    }
    SetCaretPos(xcur, ycur);

    // 参考比对原生的绘制
    DuiRect rc{rect_in.x, rect_in.y + rect_in.h, rect_in.w, rect_in.h};
    render_draw_text(mgr, rc, this->m_TextW, this->m_Color, DUI_TEXT_ALIGN_LEFT, DUI_TEXT_ALIGN_LEFT,
                     this->m_FontFamily, this->m_FontSize);
}